﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Data;
using System.Windows.Input;
using BaMusaSoft.RPS.DataModel;
using BaMusaSoft.RPS.RPSServices;
using BaMusaSoft.RPS.ViewModel.HelperClasses;
using BaMusaSoft.RPS.ViewModel.Infrastructure;
using BaMusaSoft.RPS.ViewModel.Properties;
using GalaSoft.MvvmLight.Command;
using GalaSoft.MvvmLight.Messaging;

namespace BaMusaSoft.RPS.ViewModel
{
    public class MainViewModel
    {
        private readonly RelayCommand _addScheduleCommand;
        private readonly RelayCommand _showAllSchedulesCommand;
        private readonly RelayCommand _showClaimCommand;
        private RelayCommand<string> _editScheduleCommand;
        private readonly ReadOnlyCollection<CommanCommandWrapper> _commonTaksCommand;
        private ObservableCollection<Workspace> _workspaces;
        private readonly Settings _settings;
        private static readonly object _locker = new object();
        private static MainViewModel _instance;

        private MainViewModel()
        {
            _settings = Settings.Default;
            _addScheduleCommand = new RelayCommand(ShowAddSchedule);
            _showAllSchedulesCommand = new RelayCommand(ShowAllSchedules);
            _showClaimCommand = new RelayCommand(ShowClaim);
            _editScheduleCommand = new RelayCommand<string>(EditSchedule);
            var commons = new List<CommanCommandWrapper>();
            commons.Add(new CommanCommandWrapper(AddScheduleCommand, Resources.MainWindow_Command_CreateSchedule));
            commons.Add(new CommanCommandWrapper(ShowAllSchedulesCommand, Resources.MainWindow_Command_ShowAllSchedules));
            commons.Add(new CommanCommandWrapper(ShowClaimCommand, Resources.MainWindow_Command_CreateClaim));
            _commonTaksCommand = new ReadOnlyCollection<CommanCommandWrapper>(commons);
            
            
            //string scheduleTemplatePath = _settings.ScheduleFormTemplatePath;
            //if (string.IsNullOrEmpty(scheduleTemplatePath)) scheduleTemplatePath = @"C:\";
            //SchedulePrinterHelper.StartService(scheduleTemplatePath);
            
        }
        public static MainViewModel Current
        {
            get
            {
                lock (_locker)
                {
                    return _instance ?? (_instance = new MainViewModel());
                }
            }
        }

        public ReadOnlyCollection<CommanCommandWrapper> CommonTaksCommands
        {
            get { return _commonTaksCommand; }
        }
        public ObservableCollection<Workspace> Workspaces
        {
            get
            {
                if (_workspaces == null)
                {
                    _workspaces = new ObservableCollection<Workspace>();
                    _workspaces.CollectionChanged += OnWorkspacesChanged;
                }
                return _workspaces;
            }
        }
        private void OnWorkspacesChanged(object sender, NotifyCollectionChangedEventArgs e)
        {
            if (e.NewItems != null && e.NewItems.Count != 0)
            {
                foreach (Workspace workspace in e.NewItems)
                {
                    workspace.RequestClose += OnWorkspaceRequestClose;
                }
            }
            if (e.OldItems != null && e.OldItems.Count != 0)
            {
                foreach (Workspace workspace in e.OldItems)
                {
                    workspace.RequestClose -= OnWorkspaceRequestClose;
                }
            }
        }
        private void OnWorkspaceRequestClose(object sender, EventArgs e)
        {
            var workspace = sender as Workspace;
            if (workspace == null) return;
            if (ExitPermit(workspace))
            {
                workspace.Cleanup();
                Workspaces.Remove(workspace);
            }
        }
        private void SetWorkspace(Workspace ws)
        {
            ICollectionView cv = CollectionViewSource.GetDefaultView(Workspaces);
            if (cv != null)
            {
                cv.MoveCurrentTo(ws);
            }
        }
        private bool ExitPermit(Workspace workspace)
        {
            if (workspace.HasChanges)
            {
                string s = Resources.PrompetToSaveMsg;
                return Helper.MessageConfirmed(s, workspace.MessageToken);
            }
            return true;

        }
        #region "Commands"
        public ICommand AddScheduleCommand
        {
            get { return _addScheduleCommand; }
        }
        void ShowAddSchedule()
        {
            //var workspace = Workspaces.FirstOrDefault(x => x is ScheduleViewModel) as ScheduleViewModel;
            //if (workspace == null)
            //{
                Schedule schedule = new Schedule();
                IUnitOfWork unitOfWork = new UnitOfWork();
                var workspace = new ScheduleViewModel(unitOfWork, schedule);
                Workspaces.Add(workspace);
            //}
            SetWorkspace(workspace);
            
        }
        public ICommand ShowAllSchedulesCommand
        {
            get { return _showAllSchedulesCommand; }
        }
        void ShowAllSchedules()
        {
            var workspace = Workspaces.FirstOrDefault(x => x is AllSchedulesViewModel) as AllSchedulesViewModel;
            if (workspace == null)
            {
                IUnitOfWork unitOfWork = new UnitOfWork();
                workspace = new AllSchedulesViewModel(unitOfWork);
                Workspaces.Add(workspace);
            }
            SetWorkspace(workspace);
        }
        public ICommand EditScheduleCommnad
        {
            get
            {
                return _editScheduleCommand;
            }
        }
        private void EditSchedule(string scheduleId)
        {
            if (string.IsNullOrEmpty(scheduleId)) return;
            IUnitOfWork unitOfWork = new UnitOfWork();
            var schedule = unitOfWork.Schedules.GetById(scheduleId);
            if (schedule == null) return;
            var workspace = new ScheduleViewModel(unitOfWork, schedule);
            Workspaces.Add(workspace);
            SetWorkspace(workspace);
        }
        public ICommand ShowClaimCommand
        {
            get { return _showClaimCommand; }
        }
        void ShowClaim()
        { 
            IUnitOfWork unitOfWork = new UnitOfWork();
            Claim claim = new Claim();

            Workspace workspace = new ClaimViewModel(unitOfWork, claim);
            Workspaces.Add(workspace);
            SetWorkspace(workspace);
        }

        #endregion

        #region "Public Memebers"
        public bool OkToClose
        {
            get { return !(SchedulePrinterHelper.IsBusy); }
        }
        public void StopServices()
        {
            SchedulePrinterHelper.StopService();
        }
        #endregion

       
    }
}
